﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace nsWeldController
{
    public partial class BatteryBoxCtrl : UserControl
    {
        public BatteryBoxCtrl()
        {
            InitializeComponent();
            //.Net Style Double Buffering/////////////////
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            //////////////////////////////////////////////
        }

        public List<DrawObject> drawList = new List<DrawObject>();  // 要绘制图形的列表，相对坐标为控件自身
        public List<PointF> batteryList = new List<PointF>();       // 最后得到的电池列表，相对坐标为系统实际坐标
        public PointF boxOrigin = new PointF();                     // 盒子左上角在系统中的坐标
        public float boxWidth;                                      // 盒子在系统中的实际宽度
        public float boxHeight;                                     // 盒子在系统中的实际高度

        private float lastBoxWidth;
        private float lastBoxHeight;

        public void InitializeBox(int countX, int countY)
        {
            if (countX <= 0 || countY <= 0)
            {
                return;
            }

            boxWidth = boxWidth == 0 ? (float)this.Size.Width : boxWidth;
            boxHeight = boxHeight == 0 ? (float)this.Size.Height : boxHeight;

            float batteryWidth = (float)this.Size.Width / (float)countX;
            float batteryHeight = (float)this.Size.Height / (float)countY;
            float batteryRadius = Math.Min(batteryWidth, batteryHeight) * (float)0.45;

            float locationX = 0;
            float locationY = 0;
            PointF pointCenter = new PointF();
            drawList.Clear();
            for (int i = 0; i < countY; i++)
            {
                pointCenter.Y = locationY + batteryHeight / 2;
                locationY += batteryHeight;
                for (int j = 0; j < countX; j++)
                {
                    // 使电池在电池盒上蛇形排布
                    if (i % 2 == 0)
                    {
                        locationX = batteryWidth * j;
                    }
                    else
                    {
                        locationX = batteryWidth * (countX - j - 1);
                    }
                    pointCenter.X = locationX + batteryWidth / 2;
                    Pen pen = new Pen(Color.PapayaWhip, 4);
                    CircleString circleString = new CircleString(pointCenter, batteryRadius, Color.Silver, pen, (i * countX + j + 1).ToString());
                    drawList.Add(circleString);
                    batteryList.Add(GetAbsLocation(pointCenter.X, pointCenter.Y));
                }
            }
            Invalidate();
            lastBoxWidth = (float)this.Size.Width;
            lastBoxHeight = (float)this.Size.Height;
        }

        public void DrawAreaResized()
        {
            if (drawList.Count == 0)
            {
                return;
            }
            float width = (float)this.Size.Width;
            float height = (float)this.Size.Height;
            float widthMultiplier = width / lastBoxWidth;
            float heightMultiplier = height / lastBoxHeight;
            float radiusMultiplier = Math.Min(width, height) / Math.Min(lastBoxWidth, lastBoxHeight);
            foreach (DrawObject drawObject in drawList)
            {
                if (drawObject.id == DrawType.CircleString)
                {
                    ((CircleString)drawObject).centerPoint.X *= widthMultiplier;
                    ((CircleString)drawObject).centerPoint.Y *= heightMultiplier;
                    ((CircleString)drawObject).radius *= radiusMultiplier;
                }
            }

            lastBoxWidth = width;
            lastBoxHeight = height;
        }

        private PointF GetAbsLocation(PointF pf)
        {
            PointF pointF = new PointF();
            pointF.X = Convert.ToInt32(boxOrigin.X + pf.X * boxWidth / this.Size.Width);
            pointF.Y = Convert.ToInt32(boxOrigin.Y + pf.Y * boxHeight / this.Size.Height);
            return pointF;
        }

        private Point GetAbsLocation(float x, float y)
        {
            Point point = new Point();
            point.X = Convert.ToInt32(boxOrigin.X + x * boxWidth / this.Size.Width);
            point.Y = Convert.ToInt32(boxOrigin.Y + y * boxHeight / this.Size.Height);
            return point;
        }

        private Point GetRelativeLoaction(Point pf)
        {
            Point point = new Point();
            point.X = Convert.ToInt32((pf.X - boxOrigin.X) * this.Size.Width / boxWidth);
            point.Y = Convert.ToInt32((pf.Y - boxOrigin.Y) * this.Size.Height / boxHeight);
            return point;
        }

        private void BatteryBox_Paint(object sender, PaintEventArgs e)
        {
            if ((drawList == null) || (drawList.Count == 0))
            {
                return;
            }
            
            batteryList.Clear();
            int i = 0;
            foreach (DrawObject drawObject in drawList)
            {
                ((CircleString)drawObject).str = (++i).ToString();
                drawObject.Draw(e.Graphics);
                batteryList.Add(GetAbsLocation(((CircleString)drawObject).centerPoint.X, ((CircleString)drawObject).centerPoint.Y));
            }
        }

        private void BatteryBox_MouseDown(object sender, MouseEventArgs e)
        {
            bool oneSelected = false;   // 确保只有一个图形被选中

            if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
            {
                foreach (DrawObject drawObject in drawList)
                {
                    if (drawObject.IsPointInObject(e.Location) && !oneSelected)
                    {
                        drawObject.selected = true;
                        oneSelected = true;
                        if (e.Button == MouseButtons.Right)
                        {
                            PointF pf = GetAbsLocation(((CircleString)drawObject).GetCenterPoint().X, ((CircleString)drawObject).GetCenterPoint().Y);
                            locationToolStripMenuItem.Text = pf.X.ToString() + ", " + pf.Y.ToString();
                            contextMenuStrip1.Show(this, e.Location);
                        }
                    }
                    else
                    {
                        drawObject.selected = false;
                    }
                }
                Invalidate();
            }
        }

        private void BatteryBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                foreach (DrawObject drawObject in drawList)
                {
                    if (drawObject.selected)
                    {
                        drawObject.MoveTo(new Point(e.X, e.Y));
                        break;
                    }
                }
                Invalidate();
            }
        }

        private void DeleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (DrawObject drawObject in drawList)
            {
                if (drawObject.selected)
                {
                    drawList.Remove(drawObject);
                    break;
                }
            }
            Invalidate();
        }

        private void locationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BatteryLocationSet myForm = new BatteryLocationSet();
            foreach (DrawObject drawObject in drawList)
            {
                if (drawObject.selected)
                {
                    Point point = GetAbsLocation(((CircleString)drawObject).centerPoint.X, ((CircleString)drawObject).centerPoint.Y);
                    myForm.txtLocationX.Text = point.X.ToString();
                    myForm.txtLocationY.Text = point.Y.ToString();
                    break;
                }
            }
            
            if (myForm.ShowDialog() == DialogResult.OK)
            {
                int x = 0;
                int y = 0;
                int.TryParse(myForm.txtLocationX.Text, out x);
                int.TryParse(myForm.txtLocationY.Text, out y);
                foreach (DrawObject drawObject in drawList)
                {
                    if (drawObject.selected)
                    {
                        drawObject.MoveTo(GetRelativeLoaction(new Point(x, y)));
                        break;
                    }
                }
                Invalidate();
            }
            myForm.Close();
        }

        private void BatteryBox_SizeChanged(object sender, EventArgs e)
        {
            DrawAreaResized();
            Invalidate();
        }
    }
}
